home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / msqc25t1 / sub1.c < prev    next >
C/C++ Source or Header  |  1990-09-07  |  7KB  |  276 lines

  1. /* sub1.c: A subdirectory listing utility. Enhancement of DOS DIR command.
  2.  
  3. Features of this program:
  4.  
  5.     *   All files and their attributes, plus time stamps.
  6.  
  7.     *   The number of files in each file and the space in K allocated to
  8.         it as a function of cluster size.
  9.  
  10.     *   Number of files in the directory, total bytes, and total space
  11.         taken by all files in K.
  12.  
  13.     *   Free space remaining on the disk.
  14.  
  15.  
  16. Procedure:
  17.  
  18.     1. Get and remember the current directory.
  19.     2. Find out what directory to search.
  20.     3. List the specified contents of the target directory.
  21.     4. Show summary infomation.
  22.     5. Restore the original directory.
  23.     6. Quit.
  24.  
  25.  
  26. */
  27.  
  28. #include <stdio.h>
  29. #include <dos.h>
  30. #include <io.h>
  31. #include <conio.h>
  32. #include <stdlib.h>
  33. #include <direct.h>
  34. #include <string.h>
  35. #include <malloc.h>
  36. #include <graph.h>
  37. #include "filemisc.h"
  38. #ifndef TRUE
  39. #define FALSE 0
  40. #define TRUE !FALSE
  41. #endif
  42.  
  43.  
  44. /* Globals */
  45.     char        *olddir, searchpath[80],
  46.                 filemask[13] = "*.*";
  47.     unsigned     bps, nfiles, olddrive, drive;
  48.     long        totalbytes, totalk;
  49.     int         thru;
  50.     struct diskfree_t diskinfo;
  51.  
  52. main(int argc, char *argv[])
  53. {
  54.     unsigned ndrives;
  55.     void listfiles (char*, char*), check (char*),
  56.         separate (char*, char*, char*);
  57.  
  58. /* Initialize */
  59.     olddir = getcwd (NULL, 80);     /* get current directory */
  60.     _dos_getdrive (&olddrive);      /* and drive */
  61.     totalbytes = totalk = 0L;
  62.     nfiles = 0;
  63.     drive = 0;
  64.     thru = FALSE;
  65.     strcpy (searchpath, olddir);    /* default search path */
  66.  
  67.  
  68. /* Get desired search path, change drives if necessary */
  69.     if (argc>1)
  70.         strcpy (searchpath, argv[1]);
  71.     if (searchpath[1] == ':') {
  72.         drive = (toupper (searchpath[0])) - 64;
  73.         _dos_setdrive (drive, &ndrives);
  74.     }
  75.  
  76. /* Get info about selected drive */
  77.     _dos_getdiskfree (drive, &diskinfo);    /* drive info */
  78.     bps = diskinfo.sectors_per_cluster *    /* blocksize */
  79.     diskinfo.bytes_per_sector;
  80.  
  81.  
  82. /* Show all files in current dir if so command-line arg */
  83.     if (argc == 1) {
  84.         listfiles (searchpath, filemask);
  85.         thru = TRUE;
  86.     }
  87.  
  88. /* Is command SUB <dir> or SUB <\DIR>? */
  89.     if (!thru) {
  90.             strcpy (searchpath, argv[1]);
  91.         if(chdir (searchpath) == 0) {
  92.             listfiles (searchpath, filemask);
  93.             thru = TRUE;
  94.         }
  95.     }
  96.  
  97. /* Is command SUB <dir\*.*>? */
  98.     if (!thru) {
  99.         separate (argv[1], searchpath, filemask);
  100.         if (chdir (searchpath) == 0)
  101.             if (strlen (filemask) > 0) {
  102.                 check (filemask);
  103.                 listfiles (searchpath, filemask);
  104.                 thru = TRUE;
  105.             }
  106.     }
  107.  
  108. /* Is command SUB *.*? */
  109.     if (!thru) {
  110.         strcpy (filemask, argv[1]);
  111.         check (filemask);
  112.         listfiles (olddir, filemask);
  113.         thru = TRUE;
  114.     }
  115.  
  116. /* Have we exhausted all possiblities? */
  117.     if (!thru)
  118.         puts ("PATH NOT FOUND");
  119.  
  120. /* Clean up and quit */
  121.     _dos_setdrive (olddrive, &ndrives);     /* restore drive */
  122.     chdir (olddir);                         /* and directory */
  123.     free (olddir);
  124. }                                                         /* END OF MAIN */
  125.  
  126.  
  127.  
  128. void check (char *mask)
  129. /* Check file mask, complete with wildcards if necessary */
  130. {
  131. char temp[13];
  132.  
  133.     if(mask[0] == '.') {            /* make .* into *.* */
  134.         sprintf(temp, "*%s", mask);
  135.         strcpy (mask, temp);        /* add wildcard */
  136.     }
  137.  
  138. }
  139.  
  140. void separate (char *arg, char *path, char *mask)
  141.     /* Break out path and mask from command-line arg */
  142. {
  143. char *brk;
  144.  
  145.     strcpy (path, arg);
  146.     brk = strrchr (path, '\\');     /* find last '\' in path */
  147.     if (brk) {                              /* if found */
  148.         strcpy (mask, &(brk[1])); /* copy from right to mask */
  149.         *brk = '\0';                /* chop off mask leaving path */
  150.     }
  151. }
  152.  
  153. void listfiles (char *path, char *mask)
  154.     /* List files in currently selected directory using mask */
  155. {
  156. struct find_t *file;
  157. char          *heading;
  158. unsigned        linecount, rc;
  159. unsigned        startpage (char*);
  160. void            writeinfo (struct find_t*);
  161. void            showtotals (void);
  162. unsigned        countlines (char*, unsigned);
  163.  
  164.  
  165.     /* Get space for working objects */
  166.     file = malloc (sizeof *file);
  167.     heading = malloc(160);
  168.  
  169.     /* Begin report */
  170.     sprintf(heading, "Directory for %s in %s:", mask, path);
  171.     linecount = startpage (heading);            /* first page */
  172.  
  173.     /* Write report */
  174.     rc = _dos_findfirst (mask, 0xFF, file);
  175.     while (rc == 0) {
  176.         writeinfo (file);
  177. /*        linecount = countlines (heading, linecount); */
  178.         rc = _dos_findnext (file);
  179.     }
  180.     showtotals ();
  181. }
  182.  
  183. unsigned startpage (char *header)   /* Begin output page */
  184. {
  185. /*    _clearscreen (_GCLEARSCREEN); */
  186.     puts (header);
  187.     printf("%-13s %-11s %-12s %-9s %-3s",
  188.     "Name", "Date", "Time", "Attrib", "Bytes");
  189.     return 3L;
  190. }
  191.  
  192. unsigned countlines (char *head, unsigned count)
  193.     /* Count line, start new page if full */
  194. {
  195.     ++count;
  196.     if (count == 24) {
  197.         printf ("\n-- MORE --");
  198.         getch();
  199.         count = startpage (head);
  200.     }
  201.     return count;
  202. }
  203.  
  204. void showtotals (void)      /* End report with totals */
  205. {
  206. long free, size;
  207.     /* Compute totals */
  208.     free = (long) diskinfo.avail_clusters * bps;
  209.     size = (long) diskinfo.total_clusters * bps;
  210.  
  211.     /* Report results */
  212.     printf ("\n%u files, %lu bytes, %luK space",
  213.         nfiles, totalbytes, totalk);
  214.     printf("\n%lu bytes free out of %lu", free, size);
  215. }
  216.  
  217. void writeinfo (struct find_t *f)       /* list file entry */
  218. {
  219. char    tstring[12], dstring[11], *attribs (char);
  220. unsigned kbytes (long), kb;
  221.  
  222.     /* Get file info */
  223.     datestamp (f->wr_date, dstring, NULL, NULL, NULL);
  224.     timestamp (f->wr_time, tstring, NULL, NULL, NULL);
  225.     kb = kbytes (f->size);
  226.  
  227.     /* Non-directories shown in lower case */
  228.     if (!(f->attrib & _A_SUBDIR)) strlwr (f->name);
  229.  
  230.     /* Non-directory info */
  231.     printf("\n%-14s", f->name);             /* name             */
  232.     printf("%-12s", dstring);               /* date             */
  233.     printf("%-13s", tstring);               /* time             */
  234.     printf("%-7s", attribs (f->attrib));    /* attributes       */
  235.     printf("%8lu", f->size);                /* size in bytes    */
  236. /*    printf("%6u", kb);   */                   /* size in k        */
  237.  
  238.  
  239.     /* Update sums for this entry */
  240.     totalk += kb;
  241.     totalbytes += f->size;
  242.     ++nfiles;
  243. }
  244.  
  245. char *attribs (char attrib)
  246.     /* convert attribute byte to string */
  247. {
  248. static char attr[7];
  249.  
  250.     strcpy (attr, "......");
  251.     if (attrib & _A_RDONLY) attr[5] = 'R';
  252.     if (attrib & _A_HIDDEN) attr[4] = 'H';
  253.     if (attrib & _A_SYSTEM) attr[3] = 'S';
  254.     if (attrib & _A_VOLID)  attr[2] = 'V';
  255.     if (attrib & _A_SUBDIR) attr[1] = 'D';
  256.     if (attrib & _A_ARCH)   attr[0] = 'A';
  257.     return attr;
  258. }
  259.  
  260.  
  261. unsigned kbytes (long bytes)
  262.     /* convert size to K, rounding up for cluster */
  263. {
  264. unsigned K = 0;
  265. long clust;
  266.  
  267.     if (bytes > 0L) {               /* if file not empty */
  268.         clust = bytes / bps;        /* number of clusters */
  269.         if ((clust % bps) != 0L) ++clust;   /* round up  */
  270.         if (clust == 0L) clust = 1;         /* minimum of one */
  271.         K = (clust * bps) / 1024L;          /* space in K */
  272.     }
  273.     return K;
  274. }
  275.  
  276.